Skip to content

Data-bound chart components 4/8: serve composite plan tokens - #464

Merged
masenf merged 3 commits into
stack/3-plans-and-data-varsfrom
stack/4-composite-serving
Aug 7, 2026
Merged

Data-bound chart components 4/8: serve composite plan tokens#464
masenf merged 3 commits into
stack/3-plans-and-data-varsfrom
stack/4-composite-serving

Conversation

@FarhanAliRaza

@FarhanAliRaza FarhanAliRaza commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Stacked on #463. Base is stack/3-plans-and-data-vars.

Makes xyp1|<digest>|<data token> a servable figure identity.

Change

The namespace learns one concept — what a token reveals about affinity and rebuildability — instead of branching on prefixes at each call site:

  • a composite enforces affinity through its embedded data token and rebuilds like any state token;
  • a bare xyd1 token names columns, never a figure, so it keeps affinity but is never served or rebuilt as one.

Serving a composite is plan lookup + columns (registry hit, else the data method re-run against session state) + bind into a fresh Chart. Both halves are independently recoverable on any worker, so §3.2's reconnect promise holds for this tier without a central store.

Failures are typed rather than flattened to "unknown figure token": a plan miss (hot-reload digest drift) answers err {resync} naming the digest, and a bind mismatch answers the reason naming both sides.

The registry's error seam is wired to a room-wide err broadcast here — a column republish whose bind fails has no request to answer, and without this subscribers would sit on stale pixels with nothing in the log.

The wire envelope grew no fields. Rooms, versions, mid addressing, and the attachment cap treat a composite as an ordinary fig string.

Spec

reflex-integration.md §3.6 (composite tokens, republish fan-out), file map.

Test plan

  • uv run pytest tests/reflex_adapter tests/test_validation_timing.py — 208 passed, including composite fan-out, plan-miss resync, and bind-error frames against a real uvicorn + socket.io client
  • pre-commit run --all-files, ruff check, ruff format --check, ty check — clean

Review in cubic

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 34ca1130-2c62-42ac-9aa1-6800545b92e8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Aug 5, 2026

Copy link
Copy Markdown

Greptile Summary

The PR makes composite plan/data tokens servable as figure identities and adds recovery, affinity, fan-out, and typed error handling for that tier.

  • Resolves composite figures by combining a registered plan with cached or rebuilt state-backed columns.
  • Tracks mounted plan dependencies and prunes them across subscription, release, rebuild, and TTL lifecycle transitions.
  • Adds Socket.IO integration coverage for serving, state recovery, affinity, republishing, and error responses.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
python/reflex_xy/namespace.py Adds composite-token identity, affinity, rebuild dispatch, plan binding after successful resolution, and typed request or room-wide errors.
python/reflex_xy/registry.py Extends plan-index cleanup across the transitions that end a composite mount.
python/reflex_xy/state_bridge.py Rebuilds data-backed figures by resolving plans, recovering columns from Reflex state, and binding them into fresh figures.
python/reflex_xy/app.py Wires registry-side failures to namespace room broadcasts.
spec/design/reflex-integration.md Documents composite-token serving, recovery, affinity, fan-out, and cleanup semantics.
tests/reflex_adapter/test_data_var.py Covers plan-index cleanup for unsubscribe, disconnect, release, and TTL sweep transitions.
tests/reflex_adapter/test_socket_data_plane.py Adds transport-level composite-token tests for serving, interactions, recovery, affinity, fan-out, and typed errors.

Reviews (3): Last reviewed commit: "fix(reflex): unbind plan index on every ..." | Re-trigger Greptile

Comment thread python/reflex_xy/namespace.py
Comment thread tests/reflex_adapter/test_socket_data_plane.py
@codspeed-hq

codspeed-hq Bot commented Aug 5, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 109 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing stack/4-composite-serving (0e39225) with stack/3-plans-and-data-vars (9fd4362)2

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on stack/3-plans-and-data-vars (794dae6) during the generation of this report, so 72b4f87 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 6 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread python/reflex_xy/namespace.py
Comment thread python/reflex_xy/state_bridge.py Outdated
@FarhanAliRaza
FarhanAliRaza force-pushed the stack/4-composite-serving branch from e35456f to 25a9fdc Compare August 5, 2026 14:51
@FarhanAliRaza
FarhanAliRaza force-pushed the stack/4-composite-serving branch from 25a9fdc to bf312d0 Compare August 6, 2026 13:40
@FarhanAliRaza FarhanAliRaza changed the title Data-bound chart components 4/7: serve composite plan tokens Data-bound chart components 4/8: serve composite plan tokens Aug 6, 2026
@FarhanAliRaza

Copy link
Copy Markdown
Contributor Author

Review addressed in bf312d0 — plan-index lifecycle (P2): _digests_by_data_token is now pruned on every transition that can end a mount — last unsubscribe, disconnect, release, failed-rebuild cleanup, TTL sweep, and the republish-finds-unmounted path — all funneling through _unbind_plan_if_unmounted_locked. A cached figure entry keeps the binding alive (still mounted); dropping the last of entry+subscribers drops it, so short-lived sessions no longer accumulate bindings that only a later republish would have collected. "Bounded by mounted plans" now holds unconditionally; pinned by test_data_var.py::test_unmount_transitions_drop_plan_bindings, spec updated.

masenf
masenf previously approved these changes Aug 6, 2026
FarhanAliRaza and others added 3 commits August 6, 2026 22:00
Makes xyp1|<digest>|<data token> a servable figure identity. The namespace
learns one concept — what a token reveals about affinity and
rebuildability — instead of branching on prefixes at each call site: a
composite enforces affinity through its embedded data token and rebuilds
like any state token; a bare xyd1 token names columns, never a figure, so
it keeps affinity but is never served or rebuilt as one.

Serving a composite is plan lookup + columns (registry hit, else the data
method re-run against session state) + bind into a fresh Chart. Both halves
are independently recoverable on any worker, so §3.2's reconnect promise
holds for this tier without a central store.

Failures are typed rather than flattened to "unknown figure token": a plan
miss (hot-reload digest drift) answers err {resync} naming the digest, and
a bind mismatch answers the reason, naming both sides. The registry's
error seam is wired to a room-wide err broadcast here — a column republish
whose bind fails has no request to answer, and without it subscribers would
sit on stale pixels with nothing in the log.

The wire envelope grew no fields: rooms, versions, mid addressing, and the
attachment cap treat a composite as an ordinary fig string.

Spec: reflex-integration.md §3.6 (composite tokens, republish fan-out),
file map.
The data-token -> {digests} index was inserted on subscribe but only
pruned when a republish under the same session token later found the
plan unmounted — short-lived sessions accumulated bindings forever.
Every transition that can end a mount now funnels through
_unbind_plan_if_unmounted_locked: last unsubscribe, disconnect,
release, failed-rebuild cleanup, and the TTL sweep. A cached figure
entry keeps the binding alive (still mounted); dropping the last of
entry+subscribers drops it.
The subscribe-time rebuild truncated the state's full name to its last
dotted segment while the republish fan-out used the full name, so one
mismatch produced two differently-labelled err frames (and the rebuilt
validate_columns label disagreed with both). Both state_bridge labels now
carry the full state name, matching registry._rebuild_dependent.
@masenf
masenf force-pushed the stack/4-composite-serving branch from bf312d0 to 0e39225 Compare August 6, 2026 22:08

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Greptile has paused reviews on this repository — it used its 100 free open-source review credits for this billing period. Reviews resume automatically on September 3. To continue before then, an organization admin can keep reviews running past the free credits — those bill as normal usage.

@masenf
masenf merged commit 8b7299b into main Aug 7, 2026
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants